package cuit.campus.taskRunning.user.serivce.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cuit.campus.taskRunning.commons.error.UserDeletedException;
import cuit.campus.taskRunning.commons.utils.JwtUtil;
import cuit.campus.taskRunning.commons.utils.SmsUtil;
import cuit.campus.taskRunning.user.entry.dto.UserDto;
import cuit.campus.taskRunning.user.entry.po.User;
import cuit.campus.taskRunning.user.mapper.UserMapper;
import cuit.campus.taskRunning.user.serivce.UserService;
import cuit.campus.taskRunning.commons.response.Result;
import cuit.campus.taskRunning.commons.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Autowired
    private BCryptPasswordEncoder encryptPasswordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private UserMapper userMapper;
    @Override
    public Result login(UserDto userDto) {
        log.info("1user:"+userDto);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUsername(), userDto.getPassword());
        Authentication authentication =authenticationManager.authenticate(authenticationToken);
        if(authentication == null)
            return Result.fail("用户名或密码错误");

        //TODO 加上权限
        //获取用户信息
        User user = (User)authentication.getPrincipal();
        if(user.getStatus()==1)
        {
            return Result.fail("该用户被禁用");
        }
        String userId = user.getId().toString();
        String token = jwtUtil.createJWT(userId);
        HashMap<String,Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);
        //存储用户信息
        redisCache.setCacheObject("user-login" + userId, user,2,TimeUnit.HOURS);

        //
        //返回token给前端
        return Result.ok(map,"登陆成功");
    }

    @Override
    public Result login(String phone,String code) {
        var wrapper = new LambdaQueryWrapper<User>().eq(User::getPhone, phone)
                .eq(User::getIsDelete,0).eq(User::getStatus,0);
        User user = userMapper.selectOne(wrapper);
        if(user == null)
           return Result.fail("手机号错误");
        String oldcode = redisCache.getCacheObject("phone-code" + phone);
        if(!code.equals(oldcode))
            return Result.fail("验证码错误");
        //TODO 加上权限
        String userId = user.getId().toString();
        String token = jwtUtil.createJWT(userId);
        HashMap<String,Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);
        //存储用户信息
        redisCache.setCacheObject("user-login" + userId, user,2,TimeUnit.HOURS);
        //返回token给前端
        return Result.ok(map,"登陆成功");
    }

    public boolean save(UserDto userDto){
        String code = redisCache.getCacheObject("phone-code" + userDto.getPhone());
        log.info("userDto:{}",userDto);
        log.info("code:{}",code);
        if(code != null && userDto.getVerificationCode().equals(code))
        {
            User user = new User();
            user.setUsername(userDto.getUsername());
            String newpassword = encryptPasswordEncoder.encode(userDto.getPassword());
            user.setPassword(newpassword);
            user.setPhone(userDto.getPhone());

            userMapper.insert(user);
            return true;
        }
        else
            return false;
    }

    @Override
    public Result send(UserDto userDto) {
        String code = SmsUtil.generateVerificationCode();
        log.info("phone:{}",userDto.getPhone());
        redisCache.setCacheObject("phone-code"+userDto.getPhone(),code,2, TimeUnit.MINUTES);
        return Result.ok(code);
    }

    public Result selectAllUsers() {
        List<User> list = super.list();
        return Result.ok(list);
    }


}
